#include "ds18b02.h"
#include "delay.h"
// 参考:https://blog.csdn.net/as480133937/article/details/112604303
unsigned int ds18b02_init()
{
    // 拉低
    DQ = 0;
    delay_10us(760);
    // 释放
    DQ = 1;
    // 等待
    delay_10us(60);
    // 检测从机应答,从机拉低60-240us释放
    unsigned int rep = ds18b20_check();
    return rep;
}

unsigned int ds18b02_check()
{
    int counter=0;
    while (DQ&&counter<20)
    {
       //如果高电平&&持续时间超过20u秒，从机没有回应
       counter++;
    }
    if(counter>=20){
        //从机没有回应
        return 1;
    }
    counter==0;
    while (!DQ&&counter<3)
    {
       //如果低电平&&60<低电平时间<240微秒，从机回应
        counter++;
        delay_10us(6);
    }
    if(counter>=3){
        //也就是在60us,120us,280us都是低电平，就是从机回应
        return 0;
    }
    return 1;
}

void ds18b02_send_bit(unsigned char bit_data)
{
    // 拉低
    DQ = 0;
    delay_10us(1);
    // 释放
    DQ = bit_data;
    delay_10us(5);
    DQ = 1;
}

unsigned char ds18b02_read_bit(){
     // 拉低,读时间片开始，15us读取数据
    DQ = 0;
    delay_5us();
    DQ = 1;
    //拉高后
    delay_5us();
    unsigned char bit_data=DQ;
    //保持50us,再来看看数据
    delay_10us(5);
    return bit_data;
}


void ds18b02_wite_byte(unsigned char byte_data){
    for (i = 0; i < 8; i++)
    {  
        unsigned char bit_data=byte_data&0x01;
        ds18b02_send_bit(bit_data);
        //将高位依次移动到低位
        byte_data>>=1;
        //unsigned char bit_data=byte_data&&(0x01<<i);
        //ds18b02_send_bit(bit_data);
    }
}


unsigned char ds18b02_read_byte(){
    unsigned byte_data=0x00;
    for (i = 0; i < 8; i++)
    {
       unsigned char bit_data=ds18b02_read_bit();
       //接受的数据如果是1，将改bit位改为1
       if(bit_data){
           byte_data|=0x01<<i;
       }
    }
    return byte_data;
}

//当工作在12位分辨率时，其中5个符号位，7个整数位，4个小数位
float ds18b02_read_temp(){
    // 开始转换
    ds18b02_init();
    ds18b20_write_byte(DS18B02_SKIP_ROM);//SKIP ROM
    ds18b20_write_byte(DS18B02_CONVERT);//转换命令	
    
    //开始读取
    ds18b02_init();
    ds18b20_write_byte(DS18B02_SKIP_ROM);//SKIP ROM
    ds18b02_init(DS18B02_SCRATCHPAD);//读取暂存器命令

    unsigned char ldata= ds18b02_read_byte();//读取低字节
    unsigned char mdata=  ds18b02_read_byte();//读取高字节
    //两个字节的int
    unsigned int tem_data=mdata<<8+ldata;
    // int tem_data;
    // tem_data=mdata<<8;
    // tem_data|=ldata;
    float temp;
    if((0xf800&tem_data)==0xf800){
        //高位5字节全部是1，是负数
        unsigned int value=(~tem_data)+1; //数据取反再加1,得到原码
        //乘以精度	
		temp=value*(-0.0625);
    }else{
        temp=tem_data*0.0625;
    }
    return temp;
}
